package com.naiterui.ehp.bs.cms.modules.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bs.cms.common.utils.ConfigUtil;
import com.naiterui.ehp.bs.cms.common.vo.PageParamsVO;
import com.naiterui.ehp.bs.cms.common.vo.PageVO;
import com.naiterui.ehp.bs.cms.modules.sys.utils.DictUtil;
import com.naiterui.ehp.bs.cms.modules.user.bo.record.RecordInfoBO;
import com.naiterui.ehp.bs.cms.modules.user.bo.record.RecordUserInfoBO;
import com.naiterui.ehp.bs.cms.modules.user.bo.record.RecordWorkContractBO;
import com.naiterui.ehp.bs.cms.modules.user.bo.record.ReocrdUserBaseInfoBO;
import com.naiterui.ehp.bs.cms.modules.user.entity.Licence;
import com.naiterui.ehp.bs.cms.modules.user.entity.Pharmacist;
import com.naiterui.ehp.bs.cms.modules.user.entity.StandardDict;
import com.naiterui.ehp.bs.cms.modules.user.feign.DoctorFeignClient;
import com.naiterui.ehp.bs.cms.modules.user.mapper.*;
import com.naiterui.ehp.bs.cms.modules.user.service.IPharmacistService;
import com.naiterui.ehp.bs.cms.modules.user.vo.NationVO;
import com.naiterui.ehp.bs.cms.modules.user.vo.PharmacistDetailVO;
import com.naiterui.ehp.bs.cms.modules.user.vo.PharmacistVO;
import com.naiterui.ehp.bs.cms.modules.user.vo.record.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class PharmacistServiceImpl extends ServiceImpl<PharmacistMapper, Pharmacist> implements IPharmacistService {

    @Value("${ehp.phfilepath}")
    private String phfilepath;
    @Value("${file.base.prefix}")
    private String fileBasePrefix;
    private final StandardDictMapper standardDictMapper;
    private final DoctorFeignClient doctorFeignClient;
    private final RecordUserInfoMapper recordUserInfoMapper;
    private final RecordWorkContractMapper recordWorkContractMapper;
    private final RecordWorkInfoMapper recordWorkInfoMapper;

    @Override
    public PageVO<PharmacistVO> queryPage(PageParamsVO pageParamsVO, PharmacistVO pharmacistVO) {
        QueryWrapper<PharmacistVO> entityWrapper = this.buildEntityWrapper(pageParamsVO, pharmacistVO);
        Page<PharmacistVO> page = this.baseMapper.getPage(pageParamsVO.getPage(), entityWrapper);
        return PageVO.toPageVo(page);
    }

    @Override
    public PharmacistDetailVO queryById(Long id) {
//        Pharmacist pharmacist = this.baseMapper.selectById(id);
//        PharmacistDetailVO pharmacistVO = new PharmacistDetailVO();
//        BeanUtils.copyProperties(pharmacist, pharmacistVO);
//        String sealCertNumber = this.baseMapper.getSealCertNumberByPharmacistId(id);
//        pharmacistVO.setSealCertNumber(sealCertNumber);
        return this.baseMapper.getById(id);
    }

    @Override
    public String upload(MultipartFile file, Integer type) throws IOException {
        String fileName = UUID.randomUUID() + "." + FilenameUtils.getExtension(file.getOriginalFilename());
        String imgHost = ConfigUtil.getString("pharmacist.images.url");
        String typepath = "";
        switch (type) {
            // 资格证
            case 1:
                typepath = "certificateLicence/";
                break;
            // 身份证
            case 2:
                typepath = "idcard/";
                break;
            default:
                typepath = "other/";
        }
        File newfile = new File(this.phfilepath + typepath + fileName);
        if (!newfile.exists()) {
            FileUtils.forceMkdirParent(newfile);
        }
        FileUtils.copyInputStreamToFile(file.getInputStream(), newfile);
        return imgHost + typepath + fileName;
    }

    @Override
    public List<NationVO> getNations() {
        Map<String, Object> map = new HashMap<>();
        map.put("type", StandardDict.TYPE_NATION);
        List<StandardDict> standardDictList = this.standardDictMapper.selectByMap(map);
        return standardDictList.stream().map(s -> NationVO.builder().code(s.getCode()).name(s.getName()).build()).collect(Collectors.toList());
    }

    @Override
    public RecordInfoVO recordInfo(Long userId) {
        RecordInfoVO recordInfoVO = new RecordInfoVO();

        RecordHospitalVO hospitalVO = this.doctorFeignClient.hospitalInfo();
        recordInfoVO.setHospitalInfo(hospitalVO);

        Pharmacist pharmacist = this.baseMapper.selectById(userId);
        ReocrdUserBaseInfoVO userBaseInfo = new ReocrdUserBaseInfoVO();
        userBaseInfo.setUserType(ReocrdUserBaseInfoVO.USER_TYPE_PH);
        userBaseInfo.setElectronic("/recommend/static/EHP_NTR.PNG");

        if (pharmacist == null) {
            recordInfoVO.setUserBaseInfo(userBaseInfo);
            return recordInfoVO;
        }

        userBaseInfo.setPhone(pharmacist.getPhone());
        userBaseInfo.setTitleId(pharmacist.getTitleId());
        userBaseInfo.setName(pharmacist.getName());
        userBaseInfo.setUserId(userId);

        userBaseInfo.setCertNum(pharmacist.getCardNo());
        if (StringUtils.isNoneBlank(pharmacist.getLicenseUrl())) {
            userBaseInfo.setCertUrls(Arrays.stream(pharmacist.getLicenseUrl().split(","))
                    .map(url -> ConfigUtil.getString("ehp.domain.img") + url)
                    .collect(Collectors.toList()));
        }

        userBaseInfo.setIdCardNum(pharmacist.getCardNo());

        recordInfoVO.setUserBaseInfo(userBaseInfo);

        RecordUserInfoVO recordUserInfoVO = this.recordUserInfoMapper.getByUserId(userId, ReocrdUserBaseInfoVO.USER_TYPE_PH);
        recordInfoVO.setUserInfo(recordUserInfoVO == null ? new RecordUserInfoVO() : recordUserInfoVO);

        List<RecordWorkInfoVO> workInfos = this.recordWorkInfoMapper.getByUserId(userId);
        recordInfoVO.setWorkInfos(workInfos);

        List<RecordWorkContractVO> workContracts = this.recordWorkContractMapper.getByUserId(userId);
        recordInfoVO.setWorkContracts(workContracts);
        return recordInfoVO;
    }

    @Override
    public void updateRecordInfo(RecordInfoVO recordInfoVO) throws BusinessException {
        RecordInfoBO recordInfo = new RecordInfoBO();

        BeanUtils.copyProperties(recordInfoVO, recordInfo);

        ReocrdUserBaseInfoBO userBaseInfo = new ReocrdUserBaseInfoBO();
        BeanUtils.copyProperties(recordInfoVO.getUserBaseInfo(), userBaseInfo);
        recordInfo.setUserBaseInfo(userBaseInfo);

        RecordUserInfoBO userInfo = new RecordUserInfoBO();
        BeanUtils.copyProperties(recordInfoVO.getUserInfo(), userInfo);
        recordInfo.setUserInfo(userInfo);
        List<RecordWorkContractBO> workContracts = recordInfoVO.getWorkContracts()
                .stream()
                .map(recordWorkContractVO -> {
                    RecordWorkContractBO recordWorkContractBO = new RecordWorkContractBO();
                    BeanUtils.copyProperties(recordWorkContractVO, recordWorkContractBO);
                    return recordWorkContractBO;
                }).collect(Collectors.toList());

        recordInfo.setWorkContracts(workContracts);

        this.doctorFeignClient.updateRecordInfoPh(recordInfo);
    }

    @Override
    public String uploadFile(Integer type, MultipartFile file) throws IOException {
        String path = this.getLicencePath(type);
        File filePath = new File(path);
        if (!filePath.exists()) {
            filePath.mkdirs();
        }
        String fileName = UUID.randomUUID() + "." + file.getOriginalFilename().split("\\.")[1];
        FileUtils.copyInputStreamToFile(file.getInputStream(), new File(path + fileName));
        return this.getLicenceUrl(type, fileName);
    }

    private String getLicencePath(Integer type) {
        Map<Integer, String> licencePathMap = Collections.unmodifiableMap(new HashMap<Integer, String>() {
            {
                this.put(Licence.DOCTOR_LICENCE_TYPE_AVATAR, "/" + PharmacistServiceImpl.this.fileBasePrefix + "/pharmacisrt/images/photo/%d/");
                this.put(Licence.DOCTOR_LICENCE_TYPE_MEDICAL, "/" + PharmacistServiceImpl.this.fileBasePrefix + "/pharmacisrt/images/vocatecer/%d/");
                this.put(Licence.DOCTOR_LICENCE_TYPE_IDCARD, "/" + PharmacistServiceImpl.this.fileBasePrefix + "/pharmacisrt/images/idCard/%d/");
                this.put(Licence.DOCTOR_LICENCE_TYPE_QUALIFICATION_CERTIFICATE,
                        "/" + PharmacistServiceImpl.this.fileBasePrefix + "/pharmacisrt/images/certificateLicence/%d/");
                this.put(Licence.DOCTOR_LICENCE_TYPE_SIGNATURE, "/" + PharmacistServiceImpl.this.fileBasePrefix + "/recommend/images/seal/ph/%d/");
                this.put(Licence.DOCTOR_LICENCE_CONTRACT, "/" + PharmacistServiceImpl.this.fileBasePrefix + "/pharmacisrt/images/contract/%d/");
            }
        });
        return String.format(licencePathMap.get(type), 0);
    }

    private String getLicenceUrl(Integer type, String fileName) {
        String imgHost = DictUtil.getNameByTypeAndCode("img_host_type", "1");
        Map<Integer, String> licenceUrlMap = Collections.unmodifiableMap(new HashMap<Integer, String>() {
            {
                this.put(Licence.DOCTOR_LICENCE_TYPE_AVATAR, imgHost + "/pharmacisrt/images/photo/%d/%s");
                this.put(Licence.DOCTOR_LICENCE_TYPE_MEDICAL, imgHost + "/pharmacisrt/images/vocatecer/%d/%s");
                this.put(Licence.DOCTOR_LICENCE_TYPE_IDCARD, imgHost + "/pharmacisrt/images/idCard/%d/%s");
                this.put(Licence.DOCTOR_LICENCE_TYPE_QUALIFICATION_CERTIFICATE, imgHost + "/pharmacisrt/images/certificateLicence/%d/%s");
                this.put(Licence.DOCTOR_LICENCE_TYPE_SIGNATURE, imgHost + "/recommend/images/seal/ph/%d/%s");
                this.put(Licence.DOCTOR_LICENCE_CONTRACT, imgHost + "/pharmacisrt/images/contract/%d/%s");
            }
        });
        return String.format(licenceUrlMap.get(type), 0, fileName);
    }

    private QueryWrapper<PharmacistVO> buildEntityWrapper(PageParamsVO pageParamsVO, PharmacistVO pharmacistVO) {
        QueryWrapper<PharmacistVO> entityWrapper = pageParamsVO.getEntityWrapper("t");
        entityWrapper.like(StringUtils.isNotBlank(pharmacistVO.getName()), "t.name", pharmacistVO.getName());
        entityWrapper.eq(StringUtils.isNotBlank(pharmacistVO.getPhone()), "t.phone", pharmacistVO.getPhone());
        entityWrapper.eq(StringUtils.isNotBlank(pharmacistVO.getLicenseNo()), "t.license_no", pharmacistVO.getLicenseNo());
        entityWrapper.eq(StringUtils.isNotBlank(pharmacistVO.getCardNo()), "t.card_no", pharmacistVO.getCardNo());
        entityWrapper.eq(pharmacistVO.getTitleId() != null, "t.title_id", pharmacistVO.getTitleId());
        return entityWrapper;
    }
}
